/*
 * Modelo.cpp
 *
 *  Created on: 15/06/2013
 *      Author: pato
 */

#include "Modelo.h"

Modelo::Modelo(int orden) {
	this->orden = orden;
	this->contextos = new map<string ,Contexto*>;
	if (this->orden == 1) {

	}
	Contexto* contexto = new Contexto(string(""));
	this->contextos->insert ( pair<string,Contexto*>(string(""),contexto) );

}

int Modelo::AgregarCaracter(Caracter *caracter, string cadena) {
	string contex_id = "";
	if (this->orden > 1) {
				contex_id = cadena.substr(cadena.size()-this->orden+1 , this->orden-1);
	}
	std::map<string ,Contexto*>::iterator it;
	it = this->contextos->find(contex_id);
	Contexto* contexto;
	if (it == this->contextos->end()) {
		//No existia ese contexto
		contexto = new Contexto(contex_id);
		contexto->agregarCaracter(caracter);
		this->contextos->insert ( pair<string,Contexto*>(contex_id,contexto) );
		return -1;
		}
	contexto = it->second;
	contexto->agregarCaracter(caracter);
	return 0;
}

Caracter* Modelo::buscarCaracter(Aritmetico* compresor,string contexto) {
	//Buscar el contexto que corresponda
	// Y decile al aritmetico q te descomprima un caracter
	string contex_id = "";
	if (this->orden > 1) {
			contex_id = contexto.substr(contexto.size()-this->orden+1 , this->orden-1);
	}
	Caracter* caracter = NULL;
	std::map<string ,Contexto*>::iterator it;
	it = this->contextos->find(contex_id);
	Contexto* contex;
	if (it == this->contextos->end()) {
		//No existia ese contexto
		contex = new Contexto(contex_id);
		caracter = contex->descomprimiCaracter(compresor);
		this->contextos->insert ( pair<string,Contexto*>(contex_id,contex) );
		return caracter;
	}
	contex = it->second;
	caracter = contex->descomprimiCaracter(compresor);
	return caracter;
}

int Modelo::ComprimirCaracter(string cntxt_ppmc, Aritmetico *compresor) {
	string contex_id = "";
	if (this->orden > 1) {
		contex_id = cntxt_ppmc.substr(cntxt_ppmc.size()-this->orden , this->orden -1);
	}
	std::map<string ,Contexto*>::iterator it;
	//separar el ultimo
	string nuevo_caracter = cntxt_ppmc.substr(cntxt_ppmc.size()-1, 1);
	Caracter* caracter = new Caracter(nuevo_caracter);
	it = this->contextos->find(contex_id);
	Contexto* contexto;
	if (it == this->contextos->end()) {
		//No existia ese contexto
		contexto = new Contexto(contex_id);
		contexto->comprimirCaracter(caracter, compresor);
		this->contextos->insert ( pair<string,Contexto*>(contex_id,contexto) );
		return -1;
	}
	contexto = it->second;
	if (contexto->comprimirCaracter(caracter, compresor) != 0) {
		return -1;
	}
	return 0;
}

int Modelo::TerminarCompresion(string cadena, Aritmetico *compresor) {
	string contex_id = "";
	if (this->orden > 1) {
		contex_id = cadena.substr(cadena.size()-this->orden, this->orden);
	}
	std::map<string ,Contexto*>::iterator it;
	it = this->contextos->find(contex_id);
	Caracter* caracter = new Caracter(EoF);
	Contexto* contexto;
	if (it == this->contextos->end()) {
		//No existia ese contexto
		contexto = new Contexto(contex_id);
		contexto->comprimirCaracter(caracter, compresor);
		this->contextos->insert ( pair<string,Contexto*>(contex_id,contexto) );
		return -1;
	}
	contexto = it->second;
	if (contexto->comprimirCaracter(caracter, compresor) != 0) {
		return -1;
	}
	return 0;
}

Modelo::~Modelo() {
	map<string ,Contexto*>::iterator it;
	for (it = this->contextos->begin(); it != this->contextos->end(); it++)	{
	        delete(it->second);
	}
	this->contextos->clear();
	delete this->contextos;
}
